<template>
  <div class="qr-login-container">
    <div class="qr-login-card">
      <div class="qr-header">
        <h3><i class="bi bi-qr-code"></i> 扫码登录</h3>
        <p>使用小程序扫描二维码快速登录</p>
      </div>

      <div class="qr-content">
        <!-- 二维码区域 -->
        <div class="qr-code-area" v-if="!error">
          <div v-if="loading" class="qr-loading">
            <el-skeleton :rows="1" animated />
            <p>生成二维码中...</p>
          </div>
          
          <div v-else class="qr-display">
            <div class="qr-wrapper">
              <img v-if="qrDataUrl" :src="qrDataUrl" alt="qr" class="qr-img" />
              
              <!-- 扫码状态覆盖层：为确保二维码显示，临时关闭遮罩 -->
              <div v-if="false" class="qr-overlay">
                <div v-if="scanStatus === 'scanned'" class="scan-success">
                  <el-icon size="40"><SuccessFilled /></el-icon>
                  <p>扫码成功</p>
                  <p class="scan-tip">请在手机上确认登录</p>
                </div>
                
                <div v-else-if="scanStatus === 'confirmed'" class="scan-confirmed">
                  <el-icon size="40"><CircleCheckFilled /></el-icon>
                  <p>登录成功</p>
                  <p class="scan-tip">正在跳转...</p>
                </div>
                
                <div v-else-if="scanStatus === 'expired'" class="scan-expired">
                  <el-icon size="40"><RefreshRight /></el-icon>
                  <p>二维码已过期</p>
                  <el-button type="primary" @click="generateQRCode">刷新二维码</el-button>
                </div>
              </div>
            </div>
            
            <div class="qr-tips">
              <div class="tip-item">
                <i class="bi bi-phone"></i>
                <span>打开fang旅小程序</span>
              </div>
              <div class="tip-item">
                <i class="bi bi-upc-scan"></i>
                <span>扫描上方二维码</span>
              </div>
              <div class="tip-item">
                <i class="bi bi-check-circle"></i>
                <span>确认登录即可</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 错误状态 -->
        <div v-if="error" class="qr-error">
          <el-result icon="error" title="加载失败" :sub-title="error">
            <template #extra>
              <el-button type="primary" @click="generateQRCode">重新加载</el-button>
            </template>
          </el-result>
        </div>

        <!-- 操作按钮 -->
        <div class="qr-actions">
          <el-button @click="generateQRCode" :loading="loading">
            <el-icon><Refresh /></el-icon>
            刷新二维码
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { ElButton, ElIcon, ElSkeleton, ElResult, ElMessage } from 'element-plus'
import { SuccessFilled, CircleCheckFilled, RefreshRight, Refresh } from '@element-plus/icons-vue'
import QRCode from 'qrcode'

// 云函数URL化地址（请替换为你的实际地址）
const BASE = 'https://fc-mp-77def827-a81a-4125-8389-94d01ea341a3.next.bspapp.com/api/qr-login'
// const BASE = (window as any).__QR_LOGIN_BASE__ || ''

interface QRLoginResponse {
  qrId: string
  qrData: string
  expiresIn: number
}

interface LoginStatusResponse {
  status: 'waiting' | 'scanned' | 'confirmed' | 'expired' | 'cancelled'
  token?: string
  userInfo?: any
}

// 发射事件
const emit = defineEmits<{
  loginSuccess: [token: string, userInfo: any]
}>()

// 响应式数据
const loading = ref(false)
const error = ref('')
const qrCanvas = ref<HTMLCanvasElement>()
const currentQrId = ref('')
const scanStatus = ref<'waiting' | 'scanned' | 'confirmed' | 'expired'>('waiting')
const qrDataUrl = ref('')

// 轮询相关
let pollTimer: number | null = null
let expireTimer: number | null = null

// 生成二维码
const generateQRCode = async () => {
  try {
    loading.value = true
    error.value = ''
    scanStatus.value = 'waiting'
    
    // 清除之前的定时器
    clearTimers()
    
    // 调用云对象URL化：/qr-login/generate
    const genUrl = `${BASE}/generate?domain=${encodeURIComponent(window.location.host)}`
    const response = await fetch(genUrl, { method: 'GET', mode: 'cors' })
    console.log('生成二维码:', response)
    if (!response.ok) {
      throw new Error('生成二维码失败')
    }
    
    const raw = await response.json().catch(() => ({}))
    // 云对象URL化直接返回对象，这里做兼容处理
    const payload: any = (raw && (raw.result || raw.data || raw)) || {}
    console.log('生成二维码返回:', payload)

    // 兼容多种云函数返回结构
    const data: QRLoginResponse = {
      qrId: payload.qrId,
      qrData: payload.qrData,
      expiresIn: payload.expiresIn || 120
    }
    
    currentQrId.value = data.qrId

    // 若后端未返回 qrData，则本地构造一份可扫的 deeplink
    // if (!data.qrData && data.qrId) {
    //   data.qrData = `fangtravel://qr-login?qrId=${encodeURIComponent(data.qrId)}&timestamp=${Date.now()}&domain=${encodeURIComponent(window.location.host)}`
    // }
    if (!data.qrData) {
      throw new Error('后端未返回二维码数据(qrData)')
    }
    
    // 等待DOM更新后绘制二维码
    await nextTick()
    await drawQRCode(data.qrData)
    
    // 开始轮询状态
    startPolling()
    
    // 设置过期定时器
    expireTimer = window.setTimeout(() => {
      scanStatus.value = 'expired'
      clearTimers()
    }, data.expiresIn * 1000)
    
    ElMessage.success('二维码生成成功')
    
  } catch (err: any) {
    error.value = err.message || '生成二维码失败'
    ElMessage.error(error.value)
  } finally {
    loading.value = false
  }
}

// 绘制二维码（优先使用图片，避免个别环境下canvas空白）
const drawQRCode = async (qrData: string) => {
  try {
    // 先生成图片数据（多数环境最稳定）
    const dataUrl = await QRCode.toDataURL(qrData, {
      width: 200,
      margin: 2,
      errorCorrectionLevel: 'M',
      color: { dark: '#000000', light: '#FFFFFF' }
    })
    qrDataUrl.value = dataUrl

    // 再尝试绘制到 canvas（可选，失败不影响显示）
    if (qrCanvas.value) {
      try {
        await QRCode.toCanvas(qrCanvas.value, qrData, {
          width: 200,
          margin: 2,
          errorCorrectionLevel: 'M',
          color: { dark: '#000000', light: '#FFFFFF' }
        })
      } catch (e) {
        // 忽略canvas失败，以图片显示为准
        console.warn('canvas绘制二维码失败，使用图片显示', e)
      }
    }
  } catch (err) {
    console.error('二维码生成失败，尝试使用备用服务:', err)
    // 兜底：使用在线服务生成静态二维码图片，确保不空白
    qrDataUrl.value = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(qrData)}`
  }
}

// 开始轮询登录状态
const startPolling = () => {
  pollTimer = window.setInterval(async () => {
    await checkLoginStatus()
  }, 2000) // 每2秒轮询一次
}

// 检查登录状态
const checkLoginStatus = async () => {
  if (!currentQrId.value) return
  
  try {
    // 查询二维码状态（推荐GET带query参数）
    const url = `${BASE}/status?qrId=${encodeURIComponent(currentQrId.value)}`
    const response = await fetch(url, { method: 'GET', mode: 'cors' })
    
    if (!response.ok) {
      throw new Error('检查状态失败')
    }
    
    const data: LoginStatusResponse = await response.json()
    
    switch (data.status) {
      case 'scanned':
        scanStatus.value = 'scanned'
        break
        
      case 'confirmed':
        scanStatus.value = 'confirmed'
        clearTimers()
        
        // 登录成功
        if (data.token && data.userInfo) {
          setTimeout(() => {
            emit('loginSuccess', data.token!, data.userInfo)
          }, 1500) // 延迟1.5秒显示成功动画
        }
        break
        
      case 'expired':
        scanStatus.value = 'expired'
        clearTimers()
        break
        
      case 'cancelled':
        scanStatus.value = 'waiting'
        ElMessage.warning('用户取消了登录')
        break
    }
    
  } catch (err: any) {
    console.error('检查登录状态失败:', err)
  }
}

// 清除定时器
const clearTimers = () => {
  if (pollTimer) {
    window.clearInterval(pollTimer)
    pollTimer = null
  }
  
  if (expireTimer) {
    window.clearTimeout(expireTimer)
    expireTimer = null
  }
}


// 组件挂载时生成二维码
onMounted(() => {
  generateQRCode()
})

// 组件卸载时清除定时器
onUnmounted(() => {
  clearTimers()
})
</script>

<style scoped>
.qr-login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 20px;
}

.qr-login-card {
  background: white;
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
  overflow: hidden;
  max-width: 400px;
  width: 100%;
}

.qr-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  text-align: center;
  padding: 30px 20px;
}

.qr-header h3 {
  margin: 0 0 10px 0;
  font-size: 1.5rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.qr-header p {
  margin: 0;
  opacity: 0.9;
  font-size: 14px;
}

.qr-content {
  padding: 30px 20px;
}

.qr-code-area {
  margin-bottom: 30px;
}

.qr-loading {
  text-align: center;
  padding: 40px 20px;
}

.qr-loading p {
  margin-top: 15px;
  color: #666;
}

.qr-display {
  text-align: center;
}

.qr-wrapper {
  position: relative;
  display: inline-block;
  margin-bottom: 25px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid #eee;
}

.qr-canvas {
  display: block;
  background: white;
  width: 200px;
  height: 200px;
}

.qr-img {
  display: block;
  width: 200px;
  height: 200px;
}

.qr-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(2px);
}

.scan-success,
.scan-confirmed,
.scan-expired {
  text-align: center;
  padding: 20px;
}

.scan-success .el-icon {
  color: #67c23a;
  margin-bottom: 10px;
}

.scan-confirmed .el-icon {
  color: #409eff;
  margin-bottom: 10px;
}

.scan-expired .el-icon {
  color: #f56c6c;
  margin-bottom: 10px;
}

.scan-success p,
.scan-confirmed p,
.scan-expired p {
  margin: 5px 0;
  font-weight: 500;
}

.scan-tip {
  font-size: 12px;
  color: #666;
  font-weight: normal !important;
}

.qr-tips {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-bottom: 20px;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: #666;
}

.tip-item i {
  width: 20px;
  text-align: center;
  color: #667eea;
  font-size: 16px;
}

.qr-error {
  text-align: center;
  padding: 20px 0;
}

.qr-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}

.qr-actions .el-button {
  flex: 1;
}

@media (max-width: 768px) {
  .qr-login-container {
    padding: 10px;
  }
  
  .qr-content {
    padding: 20px 15px;
  }
  
  .qr-actions {
    flex-direction: column;
  }
  
  .qr-actions .el-button {
    width: 100%;
  }
}
</style>
